package com.ce.pms.customer.service.impl;

import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;

import com.ce.pms.common.model.SysInfo;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.customer.dao.ICallInPersonDao;
import com.ce.pms.customer.dao.IClientDao;
import com.ce.pms.customer.dao.IIdTypeDao;
import com.ce.pms.customer.dao.IIndividualDao;
import com.ce.pms.customer.model.ClientDO;
import com.ce.pms.customer.model.GuestRecordDO;
import com.ce.pms.customer.model.IdTypeDO;
import com.ce.pms.customer.model.IndividualDO;
import com.ce.pms.customer.service.ICallInPersonService;
import com.ce.pms.customer.vo.CallInPersonVO;
import com.ce.pms.customer.vo.CustSearchVO;
import com.ce.util.BlankUtil;
import com.ce.util.DateUtil;
import com.sitechasia.webx.core.support.Page;
import com.sitechasia.webx.core.utils.base.PopulateUtil;

/**
 * 功能描述:
 * <p>
 * 版权所有：中企动力
 * <p>
 * 未经本公司许可，不得以任何方式复制或使用本程序任何部分
 *
 * @author 许海堆 Created on 2008-5-28
 * @author update on
 */
public class CallInPersonServiceImpl extends CustomerServiceImpl implements
		ICallInPersonService {

	/**
	 * Function:根据来访人员的来访id查出来访人员的个人资料和来访资料
	 *
	 * @param
	 * @return Create author:xuhaidui Create on:2008-5-30 Edit author: Edit on:
	 *         Why:
	 */
	public CallInPersonVO getCallInPersonById(Long guestRecordId) {
		CallInPersonVO callInPersonVO = new CallInPersonVO();
		GuestRecordDO guestRecordDO = callInPersonDao.findById(guestRecordId);
		PopulateUtil.populate(guestRecordDO, callInPersonVO, null, null);

		callInPersonVO.setCommingTime(DateUtil.convertDateToStr(guestRecordDO
				.getCommingTime(), "yyyy-MM-dd HH:mm"));
		callInPersonVO.setGoingTime(DateUtil.convertDateToStr(guestRecordDO
				.getGoingTime(), "yyyy-MM-dd HH:mm"));

		callInPersonVO.setParticipantId(guestRecordDO.getClient()
				.getParticipant().getParticipantId());
		callInPersonVO.setParticipantName(guestRecordDO.getClient()
				.getParticipant().getParticipantName());
		callInPersonVO.setTelephone(guestRecordDO.getClient().getParticipant()
				.getTelephone());
		IndividualDO individualDO = individualDao.findById(guestRecordDO
				.getClient().getParticipant().getParticipantId());

		SysrefcodeDO sex = individualDO.getSex();
		callInPersonVO.setSex(new Long(sex.getId()));
		callInPersonVO.setSexDisplayValue(sex.getName());

		if (!BlankUtil.isBlank(individualDO.getIdType())) {
			callInPersonVO.setCertificateType(individualDO.getIdType()
					.getIdTypeId());
			callInPersonVO.setCertificateTypeCode(individualDO.getIdType()
					.getIdTypeCode());
			callInPersonVO.setCertificateTypeName(individualDO.getIdType()
					.getIdTypeName());

		}
		callInPersonVO.setCertificateNo(individualDO.getIdNumber());

		callInPersonVO.setAppellative(individualDO.getAppellative());

		return callInPersonVO;
	}

	/**
	 * Function:增加来访人员
	 *
	 * @param
	 * @return Create author:xuhaidui Create on:2008-5-27 Edit author: Edit on:
	 *         Why:
	 */
	public void addCallInPerson(CallInPersonVO callInPersonVO) {
		SysInfo sysInfo = createInfo(callInPersonVO.getCreator());

		GuestRecordDO guestRecordDO = new GuestRecordDO(sysInfo);

		// 增加或修改个人的信息
		IndividualDO party = renewTheIndividual(callInPersonVO, sysInfo);
		// 跟据个人信息增加或查找来访人员
		ClientDO client = renewCallinByParty(party, sysInfo);

		// 保存参与人角色和客户信息
		guestRecordDO.setClient(client);
		// 保存来访信息
		guestRecordDO.setAddress(callInPersonVO.getAddress());
		guestRecordDO.setInterviewee(callInPersonVO.getInterviewee());
		guestRecordDO.setCommingTime(DateUtil.convertStrToDate(callInPersonVO
				.getCommingTime(), "yyyy-MM-dd HH:mm"));
		guestRecordDO.setGoingTime(DateUtil.convertStrToDate(callInPersonVO
				.getGoingTime(), "yyyy-MM-dd HH:mm"));
		guestRecordDO.setCausation(callInPersonVO.getCausation());
		callInPersonDao.saveObject(guestRecordDO);
	}

	/**
	 * Function:根据来访id删除来访信息（逻辑删除）
	 *
	 * @param
	 * @return Create author:xuhaidui Create on:2008-5-30 Edit author: Edit on:
	 *         Why:
	 */
	public void deleteCallInPerson(Long callInPersonId) {
		// TODO Auto-generated method stub
		callInPersonDao.deleteObjectById(callInPersonId);
	}

	/**
	 * Function:修改来访人的个人信息和来访信息
	 *
	 * @param
	 * @return Create author:xuhaidui Create on:2008-5-30 Edit author: Edit on:
	 *         Why:
	 */
	public void editCallInPerson(CallInPersonVO callInPersonVO) {
		SysInfo sysInfo = createInfo(callInPersonVO.getCreator());

		// 增加或修改个人的信息
		IndividualDO party = renewTheIndividual(callInPersonVO, sysInfo);

		// 2修改客户来访信息
		GuestRecordDO guestRecordDO = callInPersonDao.findById(callInPersonVO
				.getGuestRecordId());
		modifyInfo(guestRecordDO.getSysInfo(), callInPersonVO.getCreator());
		guestRecordDO.setAddress(callInPersonVO.getAddress());
		guestRecordDO.setInterviewee(callInPersonVO.getInterviewee());
		guestRecordDO.setCommingTime(DateUtil.convertStrToDate(callInPersonVO
				.getCommingTime(), "yyyy-MM-dd HH:mm"));
		guestRecordDO.setGoingTime(DateUtil.convertStrToDate(callInPersonVO
				.getGoingTime(), "yyyy-MM-dd HH:mm"));
		guestRecordDO.setCausation(callInPersonVO.getCausation());
		// 已经改变了clientDO中的party
		// 如果对应client的来访纪录只有一条，修改
		// 多于一条，新建
		//
		if (guestRecordDO.getClient().getParticipant() != party) {
			// if(guestRecordDO.getClient().getGuestRecords().size() > 1 ) {
			ClientDO client = renewCallinByParty(party, sysInfo);
			guestRecordDO.setClient(client);
			// } else {
			// guestRecordDO.getClient().setParticipant(party);
			// }
		}
		// 这一句可以不要
		// callInPersonDao.updateObject(guestRecordDO);

	}

	/** ********私有方法******************************* */
	/*
	 * 从callInPersonVO中取得个人信息并修改
	 */
	private IndividualDO renewTheIndividual(CallInPersonVO callInPersonVO,
			SysInfo sysInfo) {
		// 证件类型
		IdTypeDO idType = BlankUtil
				.isBlank(callInPersonVO.getCertificateType()) ? null
				: idTypeDao.findById(callInPersonVO.getCertificateType());
		// 1假如还没有来访人的个人资料，增加个人资料
		System.out.println("1start--------------");
		// 性别
		SysrefcodeDO sex = sysrefcodeDao.findById(callInPersonVO.getSex());
		IndividualDO party = individualDao.findByIdentity(idType,
				callInPersonVO.getCertificateNo());
		// 如果没有的话从VO中取得
		if (BlankUtil.isBlank(party)
				&& callInPersonVO.getGuestRecordId() != null) {
			GuestRecordDO guestRecordDO = callInPersonDao
					.findById(callInPersonVO.getGuestRecordId());
			party = individualDao.findById(guestRecordDO.getClient()
					.getParticipant().getParticipantId());
		}

		// if(BlankUtil.isBlank(party)&&
		// !BlankUtil.isBlank(callInPersonVO.getParticipantId())) {
		// party = individualDao.findById(callInPersonVO.getParticipantId());
		// }
		// 如果加载为空则新建
		if (BlankUtil.isBlank(party)) {
			party = new IndividualDO(callInPersonVO.getParticipantName(),
					sysInfo, sex, idType, callInPersonVO.getCertificateNo());
			// 持久化以便criteria
			individualDao.addIndividual(party);
		} else {
			// 不再跟据vo中的id而是跟据证件
			// todo:表中增加证件类型和号码的组合唯一约束
			// party =
			// individualDao.findById(callInPersonVO.getParticipantId());
			// 修改各属性
			party.setParticipantName(callInPersonVO.getParticipantName());
			party.setSex(sex);
			party.setIdNumber(callInPersonVO.getCertificateNo());
			party.setIdType(idType);

			// 系统的属性
			modifyInfo(party.getSysInfo(), callInPersonVO.getCreator());
		}
		party.setTelephone(callInPersonVO.getTelephone());
		party.setAppellative(callInPersonVO.getAppellative());
		return party;
	}

	private ClientDO renewCallinByParty(IndividualDO party, SysInfo sysInfo) {
		// 2 如果参与人未拥有来访人员角色则新建一来访人员
		System.out.println("2start--------------");
		// 来访人员类型
		SysrefcodeDO callin = sysrefcodeDao.getSysrefCodesByCode(
				"CS_CLIENT_CLIENT_TYPE", "005");
		Criteria cr = clientDao.criteriaFindUniqueBy("participant", party);
		cr.add(Restrictions.eq("clientType", callin));
		ClientDO client = (ClientDO) clientDao.findUnique(cr);

		if (BlankUtil.isBlank(client)) {
			// 未拥有来访人员角色,新建
			client = new ClientDO(party, sysInfo, callin);
		}
		System.out.println("2end--------------");
		return client;
	}

	private String getOrderSQL(CustSearchVO vo) {
		String retValue = "";
		if (!BlankUtil.isBlank(vo.getOrderString())) {
			String[] orderBy = vo.getOrderString().split(" ");
			if ("participantName".equalsIgnoreCase(orderBy[0])) {
				retValue = " ORDER BY " + "participant.PARTICIPANT_NAME";
			} else if ("certificateNo".equalsIgnoreCase(orderBy[0])) {
				retValue = " ORDER BY " + "individual.ID_NO";
			} else if ("commingTime".equalsIgnoreCase(orderBy[0])) {
				retValue = " ORDER BY " + "guest.COMMING_DATE";
			} else if ("goingTime".equalsIgnoreCase(orderBy[0])) {
				retValue = " ORDER BY " + "guest.GOING_DATE";
			}
			if ("desc".equalsIgnoreCase(orderBy[1])) {
				retValue = retValue + " DESC";
			}
		} else {
			// 默认排序
			retValue = " ORDER BY guest.COMMING_DATE DESC";
			// retValue =
			// " ORDER BY if(guest.MODIFY_DATE is null,guest.SYSDATE,guest.MODIFY_DATE) DESC";
		}
		return retValue;
	}

	/**
	 * Function:将List中的数组对象转换成CallInPersonVO对象,并返回List;<br/>
	 * 注：由于底层使用原生SQL，生成了数组列表，所以使用本方法。
	 *
	 * @param list
	 * @return Create author:罗军林 Create on:2008-5-29 Edit author: Edit on: Why:
	 */
	private List<CallInPersonVO> convertArrayToVO(List<Object[]> list) {
		List<CallInPersonVO> newList = new ArrayList<CallInPersonVO>();
		for (Object[] item : list) {
			CallInPersonVO callInPersonVO = new CallInPersonVO();

			callInPersonVO.setParticipantId(((BigInteger) item[0]).longValue());
			callInPersonVO.setParticipantName((String) item[1]);
			callInPersonVO.setTelephone((String) item[2]);
			callInPersonVO.setAppellative((String) item[3]);
			callInPersonVO.setSex(((BigInteger) item[4]).longValue());
			callInPersonVO.setSexDisplayValue(sysrefcodeDao.findById(
					callInPersonVO.getSex()).getName());
			callInPersonVO.setCertificateTypeName((String) item[5]);
			callInPersonVO.setCertificateNo((String) item[6]);
			callInPersonVO.setGuestRecordId(((BigInteger) item[7]).longValue());
			callInPersonVO.setAddress((String) item[8]);
			callInPersonVO.setInterviewee((String) item[9]);
			callInPersonVO.setCommingTime(DateUtil.convertDateToStr(
					(Timestamp) item[10], "yyyy-MM-dd HH:mm"));
			if (!BlankUtil.isBlank(item[11])) {
				callInPersonVO.setGoingTime(DateUtil.convertDateToStr(
						(Timestamp) item[11], "yyyy-MM-dd HH:mm"));
			}
			callInPersonVO.setCausation((String) item[12]);

			newList.add(callInPersonVO);
		}

		return newList;
	}

	/**
	 * @return List
	 * @roseuid 482A7DF603AE
	 */
	public List getCertTypeList() {
		return null;
	}

	/**
	 * Function:根据查询条件，进行分页查询
	 *
	 * @param
	 * @return Create author:xuhaidui Create on:2008-5-30 Edit author: Edit on:
	 *         Why:
	 */
	public Page queryCallInPerson(CustSearchVO custSearchVO, Integer pageSize,
			Integer pageNo) {

		List list = new ArrayList();
		StringBuffer sql = new StringBuffer();
		sql
				.append(" SELECT  participant.PARTICIPANT_ID, participant. PARTICIPANT_NAME,  participant .TELEPHONE , ");
		sql
				.append(" individual.APPELLATIVE,individual.SEX,idType.ID_TYPE_NAME,individual.ID_NO,guest.GUEST_RECORD_ID,guest.ADDRESS, ");
		sql
				.append(" guest.INTERVIEWEE,guest.COMMING_DATE,guest.GOING_DATE,guest.THING FROM CS_INDIVIDUAL individual ");
		sql
				.append(" JOIN CS_PARTICIPANT participant ON individual.INDIVIDUAL_ID=participant.PARTICIPANT_ID ");
		sql
				.append(" JOIN  CS_PARTICIPANT_ROLE role ON participant.PARTICIPANT_ID=role.PARTICIPANT_ID ");
		sql
				.append(" JOIN  CS_GUEST_RECORD guest ON role.PARTICIPANT_ROLE_ID=guest.CLIENT_ID ");
		sql
				.append(" LEFT JOIN CS_ID_TYPE idType ON idType.ID_TYPE_ID = individual.ID_TYPE_ID");
		sql.append(" WHERE 1=1 ");

		List<Object> parameter=new ArrayList<Object>();
		if (custSearchVO != null) {
			if (!BlankUtil.isBlank(custSearchVO.getCustomerName())) {
				sql.append(" AND participant. PARTICIPANT_NAME LIKE ?");
				parameter.add("%"+custSearchVO.getCustomerName()+"%");
			}
			if(!BlankUtil.isBlank(custSearchVO.getHouseNumber())){
				sql.append(" AND guest. ADDRESS=?");
				parameter.add(custSearchVO.getHouseNumber());
			}
			if (custSearchVO.getCallInStartDate() != null) {
				sql.append(" AND guest.COMMING_DATE >=?");
				parameter.add(custSearchVO.getCallInStartDate());
			}
			if (!BlankUtil.isBlank(custSearchVO.getCallInEndDate())) {
				sql.append(" AND guest.COMMING_DATE <=?");
				parameter.add(custSearchVO.getCallInEndDate());
			}
		}
//		String parameters[] = new String[list.size()];
//		for (int i = 0; i < list.size(); i++) {
//			parameters[i] = (String) list.get(i);
//		}
		sql.append(getOrderSQL(custSearchVO));
		Page page = callInPersonDao.pagedSqlQueryByPageNo(sql.toString(),
				pageNo, pageSize, parameter.toArray());

		page.setResult(convertArrayToVO(page.getResult()));

		return page;
	}

	private ICallInPersonDao	callInPersonDao;

	private IIndividualDao		individualDao;

	private IClientDao			clientDao;

	private IIdTypeDao			idTypeDao;

	public void setCallInPersonDao(ICallInPersonDao callInPersonDao) {
		this.callInPersonDao = callInPersonDao;
	}

	public void setIndividualDao(IIndividualDao individualDao) {
		this.individualDao = individualDao;
	}

	public void setClientDao(IClientDao clientDao) {
		this.clientDao = clientDao;
	}

	public void setIdTypeDao(IIdTypeDao idTypeDao) {
		this.idTypeDao = idTypeDao;
	}

}
